import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Minimize
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.Minimize
import androidx.compose.material.lightColors
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.ComposeWindow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.*
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.onPointerEvent
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.*
import jssc.SerialPort
import jssc.SerialPortList
import kotlinx.coroutines.*
import java.awt.image.BufferedImage
import java.text.SimpleDateFormat
import java.util.*
import javax.imageio.ImageIO
import kotlin.reflect.KFunction3

@Suppress("SameParameterValue")
private fun loadImageResource(path: String): BufferedImage {
    val resource = Thread.currentThread().contextClassLoader.getResource(path)
    requireNotNull(resource) { "Resource $path not found" }
    return resource.openStream().use(ImageIO::read)
}

const val DefAddress = 1
var isFind: Boolean = false
val green200 = Color(0xffa5d6a7)
val green500 = Color(0xff4caf50)
val green700 = Color(0xff388e3c)

val teal200 = Color(0xff80deea)

val LightGreenColorPalette = lightColors(
    primary = green500,
    primaryVariant = green700,
    secondary = teal200,
    onPrimary = Color.White,
    onSurface = Color.Black
)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
@Preview
fun App(composeWindow: ComposeWindow) {
    val devAddress = remember { mutableStateOf(DefAddress) }
    val currentStatus = remember { mutableStateOf(Status()) }
    val loglistState = rememberLazyListState()
    val dialogState = remember { mutableStateOf(false) }

    val logList = mutableStateListOf<String>()
    val df = SimpleDateFormat("HH:mm:ss.SSS")
    var logSwitch by remember { mutableStateOf(false) }
    var isStep by remember { mutableStateOf(false) }
    var fileDrop by remember { mutableStateOf(false) }
    val script = mutableStateListOf<String>()
    var scriptStatus by remember { mutableStateOf(false) }
    var scriptRunningLine by remember { mutableStateOf(0) }
    val scriptlistState = rememberLazyListState()

    suspend fun log(log: String) {

        logList.add("${df.format(Date())}>> $log")


        loglistState.scrollToItem(logList.size - 1)


    }

    var currentPort by remember { mutableStateOf("") }


    var serialPort: SerialPort? = null
    val isSerialPortOpened = remember { mutableStateOf(false) }
    var scriptJob: Job? = null;

    @Composable
    fun SerialChosenDialog(dialogState: MutableState<Boolean>, composableScope: CoroutineScope) {

        DialogWindow(
            title = "选择串口",
            onCloseRequest = { dialogState.value = false },
            state = rememberDialogState(position = WindowPosition(Alignment.Center))
        ) {

            Column(
                modifier = Modifier.fillMaxSize().background(Color.Gray).padding(16.dp)

            ) {
                val portNames = SerialPortList.getPortNames()
                portNames.forEach { comport ->


                    Row(verticalAlignment = Alignment.CenterVertically) {
                        RadioButton(selected = comport == currentPort, onClick = {

                            try {

                                serialPort?.closePort()
                                serialPort = SerialPort(comport)

                                serialPort!!.openPort() // 打开
                                //                                            serialPort?.addEventListener { event ->
                                //                                                event?.let {
                                //                                                    println("${it.portName} ${it.eventType} ${it.eventValue}")
                                //
                                //                                                }
                                //                                            }
                                serialPort!!.setParams(9600, 8, 1, 0) // 设置波特率、数据位、停止位、校验位
                                currentPort = comport
                            } catch (e: Exception) {
                                currentPort = e.message.toString()
                                serialPort = null
                                e.printStackTrace()
                            }
                            composableScope.launch {
                                if (serialPort == null) {
                                    log("打开串口失败,${currentPort}")
                                } else {
                                    log("打开串口:${currentPort}")

                                }
                            }


                            CoroutineScope(Dispatchers.IO).launch {
                                while (serialPort != null && serialPort!!.isOpened) {
                                    val status = readStatus(serialPort!!, devAddress.value)

                                    if (status.vailed) {
                                        if (logSwitch) composableScope.launch {
                                            log("电压：${status.vol} 频率：${status.freq}  电流：${status.current}  功率：${status.p}  功率因数：${status.pf} ")
                                        }
                                        currentStatus.value = status

                                    } else {
                                        if (logSwitch) composableScope.launch {
                                            log("读取失败")
                                        }


                                    }
                                }

                                delay(500)
                            }
                            dialogState.value = false
                            isSerialPortOpened.value = true

                        })
                        Text(
                            color = Color.Black,
                            text = comport,
                            modifier = Modifier
                                .padding(start = 4.dp)
                        )
                    }


                }

            }


        }
    }

    @Composable
    fun myTextFiled(
        title: String,
        min: Float,
        max: Float,
        defValue: Float,
        stepValue: Float,
        item: String,
        callFn: KFunction3<SerialPort, Float, Int, Boolean>,
        isEnabled: Boolean?
    ) {
        val composableScope = rememberCoroutineScope()
        Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.height(60.dp)) {
            var valueSet by remember { mutableStateOf(String.format("%.1f", defValue)) }
            //var valueOld by remember { mutableStateOf(defValue) };
            var flagAddCall = false;
            var flagMinuteCall = false;
            var flagClickCall: Boolean;
            var lastCor: Job? =null;
            var hintLabel by remember { mutableStateOf(item) }
            val onClickCall: () -> kotlin.Unit = {
                flagAddCall=false

                  lastCor = CoroutineScope(Dispatchers.IO).launch {

                    if (serialPort == null) {
                        composableScope.launch {
                            log("请先连接并打开串口")
                        }

                        return@launch
                    } else {
                        if (isStep || "电流" == item || !currentStatus.value.onOff) {
                            if (callFn(serialPort!!, valueSet.toFloat(), devAddress.value)) {
                                composableScope.launch { log("设置$item${valueSet.toFloat()}成功") }
                            } else {
                                composableScope.launch { log("设置$item${valueSet.toFloat()}失败") }
                            }
                        } else {
                            var i = 0;

                            val targetVal = valueSet.toFloat()

                            var currentVal =
                                if ("电压" == item) currentStatus.value.vol else if ("频率" == item) currentStatus.value.freq else 0f;
                            composableScope.launch { log("设置$item${currentVal}>>>>${valueSet.toFloat()}") }

                            flagClickCall = true;
                            val direction = if (targetVal > currentVal) true else false;

                            while (flagClickCall) {
                                currentVal += (if (direction) 1 else -1) * stepValue
                                if ((direction && currentVal >= targetVal) || (!direction && currentVal <= targetVal)) {
                                    currentVal = targetVal
                                    flagClickCall = false
                                }
                                if (callFn(serialPort!!, currentVal, devAddress.value)) {
                                    composableScope.launch { log("设置$item${currentVal}成功") }
                                } else {
                                    composableScope.launch { log("设置$item${currentVal}失败") }
                                }

                                delay(200);
                            }


                        }

                    }


                }


            }
            val onAddCall: () -> kotlin.Unit = {

                CoroutineScope(Dispatchers.IO).launch {
                    while (flagAddCall) {
                        if (serialPort == null) {
                            composableScope.launch {
                                log("请先连接并打开串口")
                            }

                            //return@launch
                        } else {

                            val target=valueSet.toFloat() + stepValue

                            if (callFn(serialPort!!, target, devAddress.value)) {
                                composableScope.launch { log("设置$item${target}成功") }
                                valueSet=String.format("%.1f", target.toFloat())
                            } else {
                                composableScope.launch { log("设置$item${target}失败") }
                            }


                        }

                        delay(200)
                    }

                }

            }
            val onMinuteCall: () -> kotlin.Unit = {

                CoroutineScope(Dispatchers.IO).launch {
                    while (flagMinuteCall) {
                        if (serialPort == null) {
                            composableScope.launch {
                                log("请先连接并打开串口")
                            }

                            //return@launch
                        } else {
                            val target=valueSet.toFloat() - stepValue
                            if (callFn(serialPort!!, target, devAddress.value)) {
                                composableScope.launch { log("设置$item${target}成功") }
                                valueSet=String.format("%.1f", target.toFloat())

                            } else {
                                composableScope.launch { log("设置$item${target}失败") }
                            }


                        }

                        delay(200)
                    }

                }

            }
            Button(
                modifier = Modifier.width(130.dp).height(50.dp).offset(y = 6.dp),
                onClick = onClickCall,
                enabled = isEnabled ?: isSerialPortOpened.value
            ) {
                Text(title)
                AnimatedVisibility(
                    visible = !isSerialPortOpened.value,
                    enter = fadeIn(initialAlpha = 0.3f),
                    exit = fadeOut()
                ) {
                    CircularProgressIndicator(
                        modifier = Modifier.padding(0.dp).size(16.dp).offset(8.dp)
                    )
                }
            }
            Spacer(modifier = Modifier.width(10.dp))
            Column {
                Box(
                    //containerColor = MaterialTheme.colorScheme.secondaryContainer,
                    //contentColor = MaterialTheme.colorScheme.secondary,
                    //onClick = if(stepValue>0)onAddCall else onClickCall,
                    modifier = Modifier.width(25.dp).height(25.dp).offset(y = 6.dp).pointerInput(Unit) {
                        awaitPointerEventScope {
                            while (true) {
                                val event = awaitPointerEvent()
                                val position = event.changes.first().position
                                if (event.type == PointerEventType.Press) {
                                    flagAddCall = true
                                    onAddCall();
                                } else if (event.type == PointerEventType.Release) {
                                    flagAddCall = false

                                }


                            }
                        }
                    },
                ) {
                    Icon(Icons.Rounded.Add,"+")
                   // Text("+", color = Color.Black)

                }
                Spacer(modifier = Modifier.height(2.dp))
                Box(
                    //containerColor = MaterialTheme.colorScheme.secondaryContainer,
                    //contentColor = MaterialTheme.colorScheme.secondary,
                    //onClick = if(stepValue>0)onAddCall else onClickCall,
                    modifier = Modifier.width(25.dp).height(25.dp).offset(y = 6.dp).pointerInput(Unit) {
                        awaitPointerEventScope {
                            while (true) {
                                val event = awaitPointerEvent()
                                val position = event.changes.first().position
                                if (event.type == PointerEventType.Press) {
                                    flagMinuteCall = true
                                    onMinuteCall();
                                } else if (event.type == PointerEventType.Release) {
                                    flagMinuteCall = false

                                }


                            }
                        }
                    },
                ) {
                    Icon(Icons.Rounded.Minimize,"-")
                    // Text("+", color = Color.Black)

                }

            }
            Spacer(modifier = Modifier.width(10.dp))
            //                        val rainbowColors: List<Color> =
            //                            listOf(Color.Red, Color.Yellow, Color.Green, Color.Cyan, Color.Blue)
            //                        val brush = remember {
            //                            Brush.linearGradient(
            //                                colors = rainbowColors
            //                            )
            //                        }
            OutlinedTextField(
                valueSet,
                textStyle = TextStyle(color = Color.Red, fontWeight = FontWeight.Bold, fontSize = 20.sp),
                onValueChange = { value ->

                    val vv = value.filter {
                        it.isDigit() || it == '.'
                    }
                    println("$value>>>$vv")
                    try {
                        //valueOld = valueSet.toFloat()
                        if (vv.isEmpty()) {
                            valueSet = String.format("%.1f", min)
                            hintLabel = item
                        } else if (vv.toFloat() in min..max) {
                            valueSet = String.format("%.1f", vv.toFloat())
                            hintLabel = item
                        } else if (vv.toFloat() < min) {
                            valueSet = String.format("%.1f", min)
                            hintLabel = "不能低于${min}"
                        } else if (vv.toFloat() > max) {
                            valueSet = String.format("%.1f", max)
                            hintLabel = "不能大于${max}"

                        }
                    } catch (e: Exception) {
                        valueSet = String.format("%.1f", min)
                        hintLabel = "请输入数字"
                    }


                },
                modifier = Modifier.onPreviewKeyEvent {
                    if (it.key == Key.Enter && it.type == KeyEventType.KeyUp) {
                        onClickCall()
                         return@onPreviewKeyEvent true
                    }
                    var float = 0.0f
                    var re = true

                    when {
                        (it.isShiftPressed && it.key == Key.DirectionUp && it.type == KeyEventType.KeyUp) -> {
                            float = 10*stepValue
                        }

                        (it.isCtrlPressed && it.key == Key.DirectionUp && it.type == KeyEventType.KeyUp) -> {
                            float = 5*stepValue
                        }

                        (it.key == Key.DirectionUp && it.type == KeyEventType.KeyUp) -> {
                            float = 1*stepValue
                        }

                        (it.isShiftPressed && it.key == Key.DirectionDown && it.type == KeyEventType.KeyUp) -> {
                            float = -10*stepValue
                        }

                        (it.isCtrlPressed && it.key == Key.DirectionDown && it.type == KeyEventType.KeyUp) -> {
                            float = -5*stepValue
                        }

                        (it.key == Key.DirectionDown && it.type == KeyEventType.KeyUp) -> {
                            float = -1*stepValue
                        }



                        else -> {
                            re = false
                        }
                    }
                    if (re) {
                        valueSet =  String.format("%.1f", valueSet.toFloat() + float)
                        if (valueSet.toFloat() < min) {
                            valueSet = String.format("%.1f", min)
                            hintLabel = "不能低于$min"
                        } else if (valueSet.toFloat() > max) {
                            valueSet = String.format("%.1f", max)
                            hintLabel = "不能大于$max"
                        }
                         onClickCall()
                    }
                    re
                },
                label = { Text(hintLabel) },
                isError = true
            )

        }
    }

    MaterialTheme() {

        val composableScope = rememberCoroutineScope()


        if (dialogState.value) {
            SerialChosenDialog(dialogState, composableScope)
        }

        Column(modifier = Modifier.onKeyEvent {
            if (it.isCtrlPressed && it.key == Key.Spacebar && it.type == KeyEventType.KeyUp) {

                composableScope.launch {
                    if (currentStatus.value.vailed && !currentStatus.value.onOff) {
                        if (serialPort == null) {
                            log("请先连接并打开串口")

                        } else {
                            val code = setOnoff(serialPort!!, true, devAddress.value)
                            log(errCode(code))


                        }
                    } else if (currentStatus.value.vailed && currentStatus.value.onOff) {
                        if (serialPort == null) {
                            log("请先连接并打开串口")

                        } else {
                            val code = setOnoff(serialPort!!, false, devAddress.value)
                            log(errCode(code))


                        }
                    } else {
                        log("请先连接并打开串口")
                    }
                }

                return@onKeyEvent true
            } else
                false
        }) {


            Row(
                Modifier
                    .background(Color.Gray)
                    .fillMaxWidth()
                    .height(500.dp)

            ) {


                Column(
                    Modifier
                        .background(Color.LightGray)
                        .padding(16.dp)
                        .fillMaxHeight()
                        .width(320.dp)

                ) {

                    ElevatedCard(
                        elevation = CardDefaults.cardElevation(
                            defaultElevation = 10.dp
                        ),
                        modifier = Modifier.fillMaxWidth()
                    ) {

                        Column(
                            modifier = Modifier.background(color = Color.Gray).fillMaxWidth().padding(12.dp)

                        ) {
                            Text("当前串口:$currentPort  ")

                            Text(
                                text = "设备地址：0X${String.format("%02X", devAddress.value)}  ",
                                Modifier.padding(0.dp, 16.dp, 0.dp, 0.dp)
                            )



                            Spacer(modifier = Modifier.height(12.dp))

                            Row {
                                Button(onClick = { dialogState.value = true }) {
                                    Text("选择串口")
                                }
                                Spacer(modifier = Modifier.width(12.dp))

                                Button(onClick = {
                                    serialPort?.closePort()
                                    isSerialPortOpened.value = false
                                    serialPort = null


                                }) {
                                    Text("停用串口")
                                }
                            }
                        }


                    }


                    Spacer(modifier = Modifier.height(20.dp))

                    //Text(nextAddr)
                    myTextFiled(
                        "设置电压",
                        0.0f,
                        300.0f,
                        220f,
                        1f,
                        "电压",
                        ::setVol, null
                    )
                    Spacer(modifier = Modifier.height(20.dp))
                    myTextFiled(
                        "设置频率",
                        40.0f,
                        100.0f,
                        50f,
                        0.1f,
                        "频率",
                        ::setFreq, null
                    )

                    Spacer(modifier = Modifier.height(20.dp))

                    myTextFiled(
                        "电流上限",
                        0.0f,
                        100.0f,
                        5f,
                        0.1f,
                        "电流上限",
                        ::setCurrent, currentStatus.value.vailed && !currentStatus.value.onOff
                    )

                    Spacer(modifier = Modifier.height(20.dp))


                    Row() {

                        Button(modifier = Modifier.width(100.dp), onClick = {
                            setOnoff(serialPort!!, true, devAddress.value)
                            composableScope.launch {
                                if (serialPort == null) {
                                    log("请先连接并打开串口")

                                } else {
                                    val code = setOnoff(serialPort!!, true, devAddress.value)
                                    log(errCode(code))


                                }
                            }


                        }, enabled = currentStatus.value.vailed && !currentStatus.value.onOff) {
                            Text("启动")
                            AnimatedVisibility(
                                visible = !isSerialPortOpened.value,
                                enter = fadeIn(initialAlpha = 0.3f),
                                exit = fadeOut()
                            ) {
                                CircularProgressIndicator(
                                    modifier = Modifier.padding(0.dp).size(16.dp).offset(8.dp)
                                )
                            }
                        }
                        Spacer(modifier = Modifier.width(10.dp))
                        Button(modifier = Modifier.width(100.dp), onClick = {
                            composableScope.launch {
                                if (serialPort == null) {
                                    log("请先连接并打开串口")

                                } else {
                                    val code = setOnoff(serialPort!!, false, devAddress.value)
                                    log(errCode(code))


                                }
                            }
                        }, enabled = currentStatus.value.vailed && currentStatus.value.onOff) {
                            Text("关闭")
                            AnimatedVisibility(
                                visible = !isSerialPortOpened.value,
                                enter = fadeIn(initialAlpha = 0.3f),
                                exit = fadeOut()
                            ) {
                                CircularProgressIndicator(
                                    modifier = Modifier.padding(0.dp).size(16.dp).offset(8.dp)
                                )
                            }
                        }
                        Spacer(modifier = Modifier.width(20.dp))
                        Row(verticalAlignment = Alignment.CenterVertically) {
                            if (isStep) Text("跳变") else Text("渐变")
                            Spacer(modifier = Modifier.width(5.dp))
                            Switch(
                                checked = isStep,
                                onCheckedChange = {
                                    isStep = it
                                },
                                thumbContent = if (isStep) {
                                    {
                                        Icon(
                                            imageVector = Icons.Filled.Check,
                                            contentDescription = null,
                                            modifier = Modifier.size(SwitchDefaults.IconSize),
                                        )
                                    }
                                } else {
                                    null
                                }
                            )
                        }


                    }


                }







                Column(

                    modifier = Modifier
                        .background(Color.DarkGray)
                        .padding(32.dp)
                        .fillMaxHeight()


                        .weight(0.5F),
                    horizontalAlignment = Alignment.CenterHorizontally

                ) {
                    Text(
                        "状态：${if (currentStatus.value.onOff) "开" else "关"}",
                        color = Color.White,
                        fontSize = 28.sp,
                        textAlign = TextAlign.Start,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Text(
                        "电压：${currentStatus.value.vol} V",
                        color = Color.White,
                        fontSize = 28.sp,
                        textAlign = TextAlign.Start,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Text(
                        "频率：${currentStatus.value.freq} Hz",
                        color = Color.White,
                        fontSize = 28.sp,
                        textAlign = TextAlign.Start,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Text(
                        "电流：${currentStatus.value.current} A",
                        color = Color.White,
                        fontSize = 28.sp,
                        textAlign = TextAlign.Start,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Text(
                        "功率：${currentStatus.value.p} W",
                        color = Color.White,
                        fontSize = 28.sp,
                        textAlign = TextAlign.Start,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))
                    Text(
                        "功率因数：${currentStatus.value.pf}",
                        color = Color.White,
                        fontSize = 28.sp,
                        textAlign = TextAlign.Start,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Spacer(modifier = Modifier.height(24.dp))


                }

                Column(

                    modifier = Modifier
                        .background(Color.DarkGray)
                        .padding(32.dp)
                        .fillMaxHeight()


                        .weight(0.7F),
                    horizontalAlignment = Alignment.CenterHorizontally

                ) {
                    Row(modifier = Modifier.weight(1F)) {
                        DropHerePanel(
                            modifier = Modifier.fillMaxSize()
                                .border(width = 2.dp, color = Color.White, shape = RoundedCornerShape(4.dp))
                                .padding(2.dp),
                            composeWindow = composeWindow,
                            onFileDrop = {
                                if (it.first().name.lowercase().endsWith(".txt")) {
                                    script.clear()

                                    script.addAll(it.first().readText().replace("\r", "").replace("\n", "").split(";"))

                                    fileDrop = true
                                }
                            }
                        ) {
                            if (!fileDrop) {
                                Text(
                                    text = "请拖拽TXT脚本到这里哦",
                                    fontSize = 20.sp,
                                    color = Color.White
                                )
                            } else {
                                Row(
                                    Modifier
                                        .background(Color.Gray)
                                        .padding(4.dp)
                                        .fillMaxSize()

                                ) {

                                    LazyColumn(state = scriptlistState, modifier = Modifier.weight(100F)) {

                                        if (script.isNotEmpty()) {

                                            for (i in 0..<script.size) {

                                                item(key = i) {
                                                    Text(
                                                        script[i],
                                                        color = if (i == scriptRunningLine) Color.Red else Color.Black,
                                                        fontSize = 18.sp
                                                    )

                                                }
                                            }
                                        }

                                    }
                                    VerticalScrollbar(
                                        modifier = Modifier.align(Alignment.CenterVertically).fillMaxHeight()
                                            .weight(1f),
                                        adapter = rememberScrollbarAdapter(
                                            scrollState = scriptlistState
                                        )
                                    )

                                }
                            }

                        }
                    }


                    Row(modifier = Modifier.weight(0.1F), verticalAlignment = Alignment.CenterVertically) {


                        Text("运行脚本", color = Color.White)


                        Spacer(modifier = Modifier.width(10.dp))
                        Switch(
                            checked = scriptStatus,
                            onCheckedChange = {

                                if (it) {
                                    if (scriptJob == null) {
                                        scriptStatus = true;
                                        scriptJob = CoroutineScope(Dispatchers.IO).launch {
                                            var tempPosition = 0;
                                            scriptRunningLine = 0;
                                            while (scriptStatus) {
                                                val s = script.get(scriptRunningLine)
                                                println(s)
                                                val cmd = s.split(" ")
                                                when {
                                                    (cmd[0] == "setVol") -> {
                                                        setVol(serialPort!!, cmd[1].toFloat(), devAddress.value)
                                                        scriptRunningLine = (scriptRunningLine + 1) % script.size
                                                    }

                                                    (cmd[0] == "setFreq") -> {
                                                        setFreq(serialPort!!, cmd[1].toFloat(), devAddress.value)
                                                        scriptRunningLine = (scriptRunningLine + 1) % script.size
                                                    }

                                                    (cmd[0] == "setCurrent") -> {
                                                        setCurrent(serialPort!!, cmd[1].toFloat(), devAddress.value)
                                                        scriptRunningLine = (scriptRunningLine + 1) % script.size
                                                    }

                                                    (cmd[0] == "setStatus") -> {
                                                        val code =
                                                            setOnoff(serialPort!!, cmd[1] == "1", devAddress.value)
                                                        scriptRunningLine = (scriptRunningLine + 1) % script.size
                                                    }

                                                    (cmd[0] == "sleep") -> {
                                                        println(cmd[1])
                                                        delay(cmd[1].toInt() * 1000L)
                                                        scriptRunningLine = (scriptRunningLine + 1) % script.size

                                                    }

                                                    (cmd[0] == "loopStart") -> {
                                                        tempPosition = scriptRunningLine
                                                        scriptRunningLine = (scriptRunningLine + 1) % script.size
                                                    }

                                                    (cmd[0] == "loopEnd") -> {
                                                        scriptRunningLine = tempPosition
                                                    }


                                                }


                                            }
                                            println("script end!!!!!!!!!!!!!!!")

                                        }

                                    }

                                } else {
                                    if (scriptJob != null) {
                                        scriptJob?.cancel()
                                        while (!scriptJob!!.isCompleted) {
                                            println("wait end!!!!!!!!!!!!!!!")

                                        }

                                    }


                                    scriptStatus = false
                                    scriptJob = null
                                }


                            },
                            thumbContent = if (scriptStatus) {
                                {
                                    Icon(
                                        imageVector = Icons.Filled.Check,
                                        contentDescription = null,
                                        modifier = Modifier.size(SwitchDefaults.IconSize),
                                    )
                                }
                            } else {
                                null
                            }
                        )


                    }

                }

            }


            Row(
                Modifier
                    .background(Color.Gray)
                    .padding(16.dp)
                    .fillMaxWidth()
                    .fillMaxHeight()

            ) {


                LazyColumn(state = loglistState, modifier = Modifier.weight(100F)) {

                    if (logList.isNotEmpty()) {

                        for (i in 0..<logList.size) {

                            item(key = i) {
                                Text(logList[i], color = Color.Black, fontSize = 18.sp)

                            }
                        }
                    }

                }
                VerticalScrollbar(
                    modifier = Modifier.align(Alignment.CenterVertically).fillMaxHeight().weight(1f),
                    adapter = rememberScrollbarAdapter(
                        scrollState = loglistState
                    )
                )
                Row(modifier = Modifier.weight(10f), verticalAlignment = Alignment.CenterVertically) {
                    Text(text = "日志")
                    Spacer(modifier = Modifier.width(10.dp))
                    Switch(
                        checked = logSwitch,
                        onCheckedChange = {
                            logSwitch = it
                        },
                        thumbContent = if (logSwitch) {
                            {
                                Icon(
                                    imageVector = Icons.Filled.Check,
                                    contentDescription = null,
                                    modifier = Modifier.size(SwitchDefaults.IconSize),
                                )
                            }
                        } else {
                            null
                        }
                    )
                }

            }
        }
    }


}


fun main1() =
    singleWindowApplication(

        title = "",
        state = WindowState(size = DpSize(960.dp, 820.dp), position = WindowPosition(alignment = Alignment.TopStart)),

        ) {

        App(window)
    }

fun main() = application {
    Window(

        onCloseRequest = ::exitApplication,
        title = "",
        state = rememberWindowState(width = 960.dp, height = 720.dp)
    ) {
        App(composeWindow = window)
    }

}
